# Copyright (c) 2018 Presto Labs Pte. Ltd.
# Author: leon

import hashlib
import hmac
import logging
import time
from urllib.parse import urlencode

from tornado import gen, httpclient


def _nonce():
  return str(int(time.time() * 1000))


def _apisign(request_url, secret):
  return hmac.new(secret.encode(), request_url.encode(), hashlib.sha512).hexdigest()


class BittrexHttpClient(object):
  def __init__(self, config):
    self._logger = logging.getLogger(__name__)
    self._config = config
    self._http_client = httpclient.AsyncHTTPClient()
    self._stopped = False
    self._base_url = 'https://bittrex.com/api/v1.1'

  def stop(self):
    self._stopped = True

  @gen.coroutine
  def fetch(self, complete_url: str):
    response = None
    for _ in range(0, 3):  # Try 3 times on error
      if self._stopped:
        return

      headers = {"apisign": _apisign(complete_url, self._config.api_secret)}
      req = httpclient.HTTPRequest(complete_url,
                                   headers=headers,
                                   connect_timeout=3,
                                   request_timeout=10)
      try:
        response = yield self._http_client.fetch(req)
      except httpclient.HTTPError as e:
        self._logger.debug('Bittrex http error.')
        continue

      if response.error:
        self._logger.error('Query error: %s' % (str(response.error)))
        continue
      break
    if self._stopped:
      return
    return response

  @gen.coroutine
  def get(self, path: str, params: dict = None):
    return (yield self.fetch(self._generate_complete_url(path, params)))

  def _generate_complete_url(self, path: str, params: dict = None) -> str:
    complete_path = '%s/%s?' % (self._base_url, path)
    key_and_nonce = {'apikey': self._config.api_key, 'nonce': _nonce()}
    complete_url = '%s%s&' % (complete_path, urlencode(key_and_nonce))
    if params is not None:
      complete_url += urlencode(params)
    return complete_url
